package com.aferzsoft.colorslide.classes;

import java.util.ArrayList;
import java.util.Random;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.util.Log;
import android.view.MotionEvent;

public class Grid implements GameInterface{

	private int rows;
	private int columns;
	
	private Cell[][] cells;
	private Paint paint;
	private RectF drawableGrid;
	
	public Grid( int rows, int columns, float parentWidth, float parentHeight ){
		this.rows = rows;
		this.columns = columns;
		this.cells = new Cell[this.rows][this.columns];
		this.paint = new Paint();
		this.drawableGrid = this.createDrawableGrid( parentWidth, parentHeight );
		this.createCells();
	}
	
	public int getRows(){
		return rows;
	}
	
	public int getColumns(){
		return columns;
	}

	public void createCells(){
		for(int i = 0; i < this.rows; i++){
			for(int j = 0; j < this.columns; j++){
				this.cells[i][j] = new Cell( 
						( this.drawableGrid.left + ( i * ( ( Cell.CELL_MARGIN * 2 ) + Cell.CELL_SIZE ) ) ) , 
						( this.drawableGrid.top + ( j * ( ( Cell.CELL_MARGIN * 2 ) + Cell.CELL_SIZE ) ) ) 
				);
			}
		}
		
		this.createRandomTiles();
	}
	
	public void createRandomTiles(){
		ArrayList<String> freeCells = new ArrayList<String>();
		for(int i = 0; i < this.rows; i++){
			for(int j = 0; j < this.columns; j++){
				if( !this.cells[i][j].tileExists() ){
					freeCells.add( i + "-" + j );
				}
			}
		}
		
		if( freeCells.size() > 0 ){
		    int randomIndex = new Random().nextInt(freeCells.size());
		    String[] randomCoords = freeCells.get(randomIndex).split("-");
			int posX = Integer.parseInt( randomCoords[0] );
			int posY = Integer.parseInt( randomCoords[1] );
			
			this.cells[posX][posY].setTile( new Tile(1, Tile.getRandomColor() ) );
		}else{
			// No hay huecos (fin del juego)
		}
	}
	
	public RectF createDrawableGrid( float parentWidth, float parentHeight ){
		int left = (int) ( ( ( parentWidth - ( ( ( Cell.CELL_MARGIN * this.rows ) * 2 ) + ( ( Cell.CELL_SIZE * this.rows ) ) ) ) / 2 ) - ( Cell.CELL_MARGIN / 2 ) );
		int top = (int) ( ( ( parentHeight - ( ( ( Cell.CELL_MARGIN * this.columns ) * 2 ) + ( ( Cell.CELL_SIZE * this.columns ) ) ) ) / 2 ) - ( Cell.CELL_MARGIN / 2 ) );
		int right = (int) (left + ( ( Cell.CELL_MARGIN * this.rows ) * 2 ) + ( Cell.CELL_SIZE * this.rows ) + ( Cell.CELL_MARGIN ) );
		int bottom = (int) (top + ( ( Cell.CELL_MARGIN * this.columns ) * 2 ) + ( Cell.CELL_SIZE * this.columns ) + ( Cell.CELL_MARGIN ) );
		Log.i("TEST", new RectF( left, top, right, bottom ).toString() );
		return new RectF( left, top, right, bottom );
	}
	
	public void swipeUp(){
		boolean validMove = false;
		for(int i = 0; i < this.rows; i++){
			for(int j = 0; j < this.columns; j++){
				if( this.cells[i][j].tileExists()){
					
					int cellWithoutTile = -1;				// Cell without tile. It can be positioned here.
					int cellWithEqualColorTile = -1;		// Cell contains tile with equal color found. It can merge.
					
					/* Looks for the nearest cell without tile or the nearest cell with tile with the same color that current */
					for( int h = 0; h < j; h++){
						if( !this.cells[i][h].tileExists() ){
							if( cellWithoutTile == -1 ) cellWithoutTile = h;
						}else if( this.cells[i][h].getTile().getColor() ==  this.cells[i][j].getTile().getColor() ){
							cellWithEqualColorTile = h;
						}else{
							cellWithoutTile = -1;
							cellWithEqualColorTile = -1;
						}
					}
					
					/* If the nearest cell contains tile with same color, merge both into it */
					if( cellWithEqualColorTile != -1 ){
						int cellToMergeAmount = this.cells[i][cellWithEqualColorTile].getTile().getAmount();
						int currentCellAmount = this.cells[i][j].getTile().getAmount();
						this.cells[i][cellWithEqualColorTile].getTile().setAmount( cellToMergeAmount + currentCellAmount );
						this.cells[i][j].setTile( null );
						validMove = true;
					}else if( cellWithoutTile != -1 ){
						this.cells[i][cellWithoutTile].setTile( this.cells[i][j].getTile() );
						this.cells[i][j].setTile( null );
						validMove = true;
					}
					
				}
			}
		}	
		if( validMove ) this.createRandomTiles();
	}
	
	public void swipeLeft(){
		boolean validMove = false;
		for(int i = 0; i < this.rows; i++){
			for(int j = 0; j < this.columns; j++){
				if( this.cells[i][j].tileExists() ){
					int cellWithoutTile = -1;				// Cell without tile. It can be positioned here.
					int cellWithEqualColorTile = -1;		// Cell contains tile with equal color found. It can merge.
					
					/* Looks for the nearest cell without tile or the nearest cell with tile with the same color that current */
					Log.i("TEST", this.cells[i][j].getTile().toString() );
					for( int h = 0; h < i; h++){
						Log.i("TEST", "X: " + this.cells[h][j].getPosX() + " Y: " + this.cells[h][j].getPosY() + " H: " + h);
						if( !this.cells[h][j].tileExists() ){
							if( cellWithoutTile == -1 ) cellWithoutTile = h;
						}else if( this.cells[i][j].getTile().getColor() == this.cells[h][j].getTile().getColor() ){
							cellWithEqualColorTile = h;
						}else{
							cellWithoutTile = -1;
							cellWithEqualColorTile = -1;
						}
					}
					Log.i("TEST", String.valueOf( cellWithoutTile ) );
					
					/* If the nearest cell contains tile with same color, merge both into it */
					if( cellWithEqualColorTile != -1 ){
						int cellToMergeAmount = this.cells[cellWithEqualColorTile][j].getTile().getAmount();
						int currentCellAmount = this.cells[i][j].getTile().getAmount();
						this.cells[cellWithEqualColorTile][j].getTile().setAmount( cellToMergeAmount + currentCellAmount );
						this.cells[i][j].setTile( null );
						validMove = true;
					}else if( cellWithoutTile != -1 ){
						this.cells[cellWithoutTile][j].setTile( this.cells[i][j].getTile() );
						this.cells[i][j].setTile( null );
						validMove = true;
					}
				}
				
			}
		}	
		if( validMove ) this.createRandomTiles();
	}
	
	public void swipeDown(){
		boolean validMove = false;
		for(int i = this.rows - 1; i >= 0; i--){
			for(int j = this.columns - 1; j >= 0; j--){
				if( this.cells[i][j].tileExists() ){
					
					int cellWithoutTile = -1;				// Cell without tile. It can be positioned here.
					int cellWithEqualColorTile = -1;		// Cell contains tile with equal color found. It can merge.
					
					/* Looks for the nearest cell without tile or the nearest cell with tile with the same color that current */
					for( int h = this.columns - 1; h > j; h--){
						if( !this.cells[i][h].tileExists() ){
							if( cellWithoutTile == -1 ) cellWithoutTile = h;
						}else if( this.cells[i][j].getTile().getColor() == this.cells[i][h].getTile().getColor() ){
							cellWithEqualColorTile = h;
						}else{
							cellWithoutTile = -1;
							cellWithEqualColorTile = -1;
						}
					}
					
					/* If the nearest cell contains tile with same color, merge both into it */
					if( cellWithEqualColorTile != -1 ){
						int cellToMergeAmount = this.cells[i][cellWithEqualColorTile].getTile().getAmount();
						int currentCellAmount = this.cells[i][j].getTile().getAmount();
						this.cells[i][cellWithEqualColorTile].getTile().setAmount( cellToMergeAmount + currentCellAmount );
						this.cells[i][j].setTile( null );
						validMove = true;
					}else if( cellWithoutTile != -1 ){
						this.cells[i][cellWithoutTile].setTile( this.cells[i][j].getTile() );
						this.cells[i][j].setTile( null );
						validMove = true;
					}
					
				}
			}
		}	
		if( validMove ) this.createRandomTiles();
	}
	
	public void swipeRight(){
		boolean validMove = false;
		for(int i = this.rows - 1; i >= 0; i--){
			for(int j = this.columns - 1; j >= 0; j--){
				if( this.cells[i][j].tileExists() ){

					int cellWithoutTile = -1;				// Cell without tile. It can be positioned here.
					int cellWithEqualColorTile = -1;		// Cell contains tile with equal color found. It can merge.
					
					/* Looks for the nearest cell without tile or the nearest cell with tile with the same color that current */
					for( int h = this.rows - 1; h > i; h--){
						if( !this.cells[h][j].tileExists() ){
							if( cellWithoutTile == -1 ) cellWithoutTile = h;
						}else if( this.cells[i][j].getTile().getColor() == this.cells[h][j].getTile().getColor() ){
							cellWithEqualColorTile = h;
						}else{
							cellWithoutTile = -1;
							cellWithEqualColorTile = -1;
						}
					}
					
					/* If the nearest cell contains tile with same color, merge both into it */
					if( cellWithEqualColorTile != -1 ){
						int cellToMergeAmount = this.cells[cellWithEqualColorTile][j].getTile().getAmount();
						int currentCellAmount = this.cells[i][j].getTile().getAmount();
						this.cells[cellWithEqualColorTile][j].getTile().setAmount( cellToMergeAmount + currentCellAmount );
						this.cells[i][j].setTile( null );
						validMove = true;
					}else if( cellWithoutTile != -1 ){
						this.cells[cellWithoutTile][j].setTile( this.cells[i][j].getTile() );
						this.cells[i][j].setTile( null );
						validMove = true;
					}
					
				}
			}
		}	
		if( validMove ) this.createRandomTiles();
	}
	
	@Override
	public boolean onDraw( Canvas canvas ) {
		this.paint.setColor( Color.rgb(150, 150, 150) );
		this.paint.setStyle(Style.STROKE);
		this.paint.setStrokeWidth(25);
		canvas.drawRoundRect( this.drawableGrid, 15, 15, paint );
		this.paint.setColor( Color.rgb(230, 230, 230) );
		this.paint.setStyle(Style.FILL);
		canvas.drawRoundRect( this.drawableGrid, 15, 15, paint );
		
		for(int i = 0; i < this.rows; i++){
			for(int j = 0; j < this.columns; j++){
				if( this.cells[i][j].tileExists() ){
					this.cells[i][j].onDraw(canvas);
				}
			}
		}
		
		return true;
	}

	@Override
	public boolean onTouch(MotionEvent event) {
		
		return false;
	}
	
}
